<template>
	<div class="t-chart" v-bind="$attrs">
		<div v-show="!formatEmpty" class="t-chart-container" :id="id" ref="echartRef" />
		<slot v-if="formatEmpty" name="empty">
			<van-empty v-bind="$attrs" :description="description" />
		</slot>
		<slot></slot>
	</div>
</template>

<script setup lang="ts" name="TChart">
	import { useResizeObserver } from '@vueuse/core';
	// import { toLine } from '@/utils';
	import { debounce, isEmpty } from 'lodash-es';
	import { computed } from 'vue';
	import echarts from './useChart';
	const props = defineProps({
		options: {
			type: Object,
			default: () => ({}),
		},
		id: {
			type: String,
			default: () => Math.random().toString(36).substring(2, 8),
		},
		theme: {
			type: String,
			default: '',
		},
		// isEmpty: {
		// 	type: [Boolean, Function],
		// 	default: false,
		// },
		description: {
			type: String,
			default: '暂无数据',
		},
	});

	const echartRef = ref<HTMLDivElement>();
	const chart = ref();
	const emits = defineEmits(['chart']);
	// const events = Object.entries(useAttrs());

	// 图表初始化
	const renderChart = () => {
		chart.value = markRaw(echarts.init(echartRef.value, props.theme));
		setOption(props.options);
		// 返回chart实例
		emits('chart', chart.value);

		// 监听图表事件
		// events.forEach(([key]) => {
		// 	if (key.startsWith('on') && !key.startsWith('onChart')) {
		// 		const on = toLine(key).substring(3);
		// 		chart.value.on(on, (...args: any) => emits(on, ...args));
		// 	}
		// });

		// 监听元素变化
		useResizeObserver(echartRef.value, resizeChart);
		// 如果不想用vueuse，可以使用下边的方法代替，但组件使用v-show时，不会触发resize事件
		// window.addEventListener('resize', resizeChart)
	};

	// 重绘图表函数
	const resizeChart = debounce(() => {
		chart.value?.resize();
	}, 300);

	// 设置图表函数
	const setOption = debounce(async (data) => {
		if (!chart.value) return;
		chart.value.setOption(data, true, true);
		await nextTick();
		resizeChart();
	}, 300);

	const formatEmpty = computed(() => {
		// if (typeof props.isEmpty === 'function') {
		// 	return props.isEmpty(props.options);
		// }
		// return props.isEmpty;
		return isEmpty(props.options);
	});

	watch(
		() => props.options,
		async (nw) => {
			await nextTick();
			setOption(nw);
		},
		{ deep: true },
	);

	watch(
		() => props.theme,
		async () => {
			chart.value.dispose();
			renderChart();
		},
	);

	onMounted(() => {
		renderChart();
	});
	onBeforeUnmount(() => {
		// 取消监听
		// window.removeEventListener('resize', resizeChart)
		// 销毁echarts实例
		chart.value.dispose();
		chart.value = null;
	});
</script>

<style lang="less" scoped>
	.t-chart {
		position: relative;
		width: 100%;
		height: 100%;
		&-container {
			width: 100%;
			height: 100%;
		}
	}
</style>
